package app.view.mediators
{
	import app.model.proxies.InProxy;
	import app.model.proxies.OutProxy;
	
	import flash.events.Event;
	import flash.filesystem.File;
	import flash.net.FileFilter;
	
	import org.puremvc.as3.multicore.interfaces.INotification;
	import org.puremvc.as3.multicore.interfaces.IProxy;
	import org.puremvc.as3.multicore.patterns.mediator.Mediator;

	public class FileMediator extends Mediator
	{
		public static const NAME:String = "FileMediator";
		
		// incoming interests
		public static const OPEN_REQUEST:String = "file/openRequest";
		public static const SAVE_REQUEST:String = "file/saveRequest";
		public static const INCOMING_DATA:String = "file/incomingData";
		
		// outgoing notifications
		public static const CANCELED:String = "file/canceled";
		public static const FORWARD_DATA:String = "file/forwardData";
		
		private static const IN:int = 0;
		private static const OUT:int = 1;
		private static const READY:int = -1;
		
		private var _inProxy:IProxy;
		private var _outProxy:IProxy;
		private var direction:int = READY;
		private var data:Object;
		
		public function FileMediator()
		{
			super( NAME, File.documentsDirectory );			
		}
		
		override public function listNotificationInterests():Array{
			return [ 	OPEN_REQUEST,	
						INCOMING_DATA,
						SAVE_REQUEST ];
		}
		
		override public function handleNotification(note:INotification):void{
			switch(note.getName()){
				case OPEN_REQUEST:
					openFile();
					break;
					
				case INCOMING_DATA:
					incomingData( note.getType(), note.getBody() )
					break;
					
				case SAVE_REQUEST:
					saveFile( note.getBody() );
					break;
			}
		}
		
		private function incomingData( url:String, data:Object ):void{
			if(view.url != url)return;
			sendForwardDataNote( data );
			direction = READY;
		}
		private function get inProxy():InProxy{
			if(!_inProxy)_inProxy = IProxy(facade.retrieveProxy(InProxy.NAME));
			return InProxy( _inProxy );
		}
		
		private function get outProxy():OutProxy{
			if(!_outProxy)_outProxy = IProxy(facade.retrieveProxy(OutProxy.NAME));
			return OutProxy( _outProxy );
		}
		
		private function openFile():void{
			direction = IN;
			addBrowseListeners();
			var xmlFilter:FileFilter = new FileFilter("xml or fsm", "*.xml;*.fsm");
			view.browseForOpen("Browse for file", [xmlFilter])
		}
		
		private function saveFile( data:Object ):void{
			direction = OUT;
			if(view.exists && !view.isDirectory && view.extension == "fsm" ){
				outProxy.persist( view.url, data );
			}else{
				saveFileAs( data );
			}
			
		}
		
		private function saveFileAs( data:Object ):void{
			this.data = data;
			
			setViewComponent( view.parent );
			addBrowseListeners();
			view.browseForSave("save fsm");
		}
		
		private function addBrowseListeners():void{
			view.addEventListener(Event.CANCEL, onCancel);
			view.addEventListener(Event.SELECT, onSelect);
		}
		
		private function removeBrowseListeners():void{
			view.removeEventListener(Event.CANCEL, onCancel);
			view.removeEventListener(Event.SELECT, onSelect);
		}
		
		private function onCancel(event:Event):void{
			removeBrowseListeners();
			sendCancelNote();
		}
		
		private function onSelect(event:Event):void{
			removeBrowseListeners();
			if(direction == IN ){
				aquire()
			}else if(direction == OUT ){
				persist();
			}
		}
		
		private function aquire():void{
			inProxy.aquire( view.url );
		}
		
		private function persist():void{
			conformURLToFSM();
			outProxy.persist(view.url, data );
		}
		
		private function conformURLToFSM():void{
			var split:Array;
			split = view.url.split(".")
			if(split.length > 1)split.pop();
			view.url = split.join(".") + ".fsm";
		}
		
		private function sendCancelNote():void{
			sendNotification(CANCELED);
		}
		
		private function sendForwardDataNote( data:Object ):void{
			sendNotification( FORWARD_DATA, data, view.extension );
		}
		
		
		private function get view():File{
			return File( viewComponent );
		}
		
	}
}